package com.sgidi.einvoice.service;

import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xwpf.usermodel.*;


import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class FileConversionService {
    @Value(".../data/invoice")
    private String backupPath;
//    public File convertDocToPdf(MultipartFile docFile) throws IOException {
//        File outputFile = File.createTempFile("converted_document_", ".pdf");
//
//        try (XWPFDocument document = new XWPFDocument(docFile.getInputStream());
//             PDDocument pdfDoc = new PDDocument();
//             OutputStream outputStream = new FileOutputStream(outputFile)) {
//
//            PDPage page = new PDPage();
//            pdfDoc.addPage(page);
//
//            try (PDPageContentStream contentStream = new PDPageContentStream(pdfDoc, page)) {
//                for (XWPFParagraph para : document.getParagraphs()) {
//                    for (XWPFRun run : para.getRuns()) {
//                        String text = run.getText(0);
//                        contentStream.setFont(PDType1Font.HELVETICA, 12);
//                        contentStream.beginText();
//                        contentStream.newLineAtOffset(100, 700);
//                        contentStream.showText(text);
//                        contentStream.endText();
//                    }
//                }
//            }
//
//            pdfDoc.save(outputStream);
//            pdfDoc.close();
//        }
//
//        return outputFile;
//    }

    public File mergePdfFiles(List<File> pdfFiles) throws IOException {
        PDFMergerUtility mergerUtility = new PDFMergerUtility();
        String mergedFileName = UUID.randomUUID() + ".pdf";
        File file = new File(backupPath, mergedFileName);
        file.createNewFile();
        mergerUtility.setDestinationFileName(mergedFileName);


        for (File pdfFile : pdfFiles) {
            mergerUtility.addSource(pdfFile);
        }

        mergerUtility.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
        return new File(mergedFileName);
    }

    public ResponseEntity<byte[]> handleFileUpload(List<MultipartFile> files) throws IOException {
        List<File> pdfFiles = new ArrayList<>();

        for (MultipartFile file : files) {
            String contentType = file.getContentType();
            String fileName1 = UUID.randomUUID() + ".pdf";
            new File(backupPath, fileName1).createNewFile();
            File newFile = new File(backupPath, fileName1);
            OutputStream pdfOutputStream = new FileOutputStream(newFile.getAbsolutePath());

            if ("application/pdf".equals(contentType)) {
                // PDF文件直接保存
                //File pdfFile = new File(backupPath, fileName1);
                pdfOutputStream.write(file.getBytes());
                pdfFiles.add(newFile);
            } else {
                if (getFileExtension(file.getOriginalFilename()).equals("docx") || getFileExtension(file.getOriginalFilename()).equals("doc")) {
                    convertDocToPdf(file.getInputStream(), pdfOutputStream);
                } else if (getFileExtension(file.getOriginalFilename()).equals("xls") || getFileExtension(file.getOriginalFilename()).equals("xlsx")) {
                    convertXlsToPdf(file.getInputStream(), pdfOutputStream);
                } else if (getFileExtension(file.getOriginalFilename()).equals("ppt")) {
                    convertPptToPdf(file.getInputStream(), pdfOutputStream);
                } else if (getFileExtension(file.getOriginalFilename()).equals("pptx")) {
                    // DOC文件先转换为PDF
                    convertPptxToPdf(file.getInputStream(), pdfOutputStream);
                } else if (getFileExtension(file.getOriginalFilename()).equals("png") || getFileExtension(file.getOriginalFilename()).equals("jpg")) {
                    // DOC文件先转换为PDF
                    convertImgToPdf(file.getInputStream(), pdfOutputStream);
                }
                //File dest = new File(backupPath, fileName);
                pdfFiles.add(new File(backupPath, fileName1));
            }
        }

        File mergedPdf = mergePdfFiles(pdfFiles);
        byte[] pdfContent = Files.readAllBytes(mergedPdf.toPath());

        // 清理临时文件
        for (File file : pdfFiles) {
            file.delete();
        }
        mergedPdf.delete();

        return ResponseEntity.ok()
                .contentType(MediaType.APPLICATION_PDF)
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"merged.pdf\"")
                .body(pdfContent);
    }


    public ResponseEntity<byte[]> handleFileUploadByWord(List<MultipartFile> files) throws IOException {
        List<File> docxFiles = new ArrayList<>();

        for (MultipartFile file : files) {
            if (getFileExtension(file.getOriginalFilename()).equals("docx")) {
                File tempFile = new File("temp_" + UUID.randomUUID() + ".docx");
                Files.copy(file.getInputStream(), tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
                docxFiles.add(tempFile);
            }
        }

        File mergedDocx = null;
        try {
            mergedDocx = mergeDocxFiles(docxFiles,"");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        byte[] docxContent = Files.readAllBytes(mergedDocx.toPath());

        for (File file : docxFiles) {
            file.delete();
        }
        mergedDocx.delete();

        return ResponseEntity.ok()
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"merged.docx\"")
                .body(docxContent);
    }

    public File mergeDocxFiles(List<File> docxFiles, String outputPath) throws Exception {
        if (docxFiles == null || docxFiles.isEmpty()) {
            throw new IllegalArgumentException("文件列表不能为空");
        }

        // 加载第一个文档
        WordprocessingMLPackage mainDoc = WordprocessingMLPackage.load(docxFiles.get(0));
        MainDocumentPart mainDocumentPart = mainDoc.getMainDocumentPart();

        // 逐个合并其余文档
        for (int i = 1; i < docxFiles.size(); i++) {
            WordprocessingMLPackage tempDoc = WordprocessingMLPackage.load(docxFiles.get(i));
            MainDocumentPart tempPart = tempDoc.getMainDocumentPart();

            // 复制所有段落和表格
            mainDocumentPart.getContent().addAll(tempPart.getContent());
        }

        // 保存合并后的文档
        File outputFile = new File(backupPath, "merged.docx");
        mainDoc.save(outputFile);
        return outputFile;
    }




    public void convertDocToPdf(InputStream inputStream, OutputStream pdfOutputStream) {


        AsposeConvert.wordTopdfByAspose(inputStream, pdfOutputStream);

    }

    public void convertXlsToPdf(String xlsPath, String pdfPath) {
        try (InputStream xlsInputStream = new FileInputStream(xlsPath);
             OutputStream pdfOutputStream = new FileOutputStream(pdfPath)) {
            AsposeConvert.excelToPdf(xlsInputStream, pdfOutputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void convertXlsToPdf(InputStream inputStream, OutputStream pdfOutputStream) {
        try {
            //OutputStream pdfOutputStream = new FileOutputStream(pdfPath);
            AsposeConvert.excelToPdf(inputStream, pdfOutputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void convertPptToPdf(InputStream inputStream, OutputStream pdfOutputStream) {
        try {
            AsposeConvert.pptToPdf(inputStream, pdfOutputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void convertPptxToPdf(InputStream inputStream, OutputStream pdfOutputStream) {
        try {

            AsposeConvert.pptxToPdf(inputStream, pdfOutputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void convertImgToPdf(InputStream inputStream, OutputStream pdfOutputStream) {
        try {

            AsposeConvert.imgToPdf(inputStream, pdfOutputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String getFileExtension(String fileName) {
        if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
            return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
        } else {
            return "";
        }
    }
}
